package org.sag.mutation;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.wso2.balana.AbstractTarget;
import org.wso2.balana.DOMHelper;
import org.wso2.balana.Policy;
import org.wso2.balana.PolicyTreeElement;
import org.wso2.balana.Rule;
import org.wso2.balana.combine.CombinerElement;
import org.wso2.balana.combine.RuleCombiningAlgorithm;
import org.wso2.balana.combine.xacml3.DenyOverridesRuleAlg;
import org.wso2.balana.combine.xacml3.PermitOverridesRuleAlg;
import org.wso2.balana.combine.xacml3.DenyUnlessPermitRuleAlg;
import org.wso2.balana.combine.xacml3.PermitUnlessDenyRuleAlg;
import org.wso2.balana.combine.xacml2.FirstApplicableRuleAlg;
import org.wso2.balana.cond.Condition;
import org.wso2.balana.ctx.AbstractResult;
import org.wso2.balana.xacml3.Target;

public class PolicyMutator {
    
	private Policy policy;
	private String mutantFileNameBase;
	private ArrayList<PolicyMutant> mutantList = new ArrayList<PolicyMutant>();
	
	public PolicyMutator(String policyFilePath) throws Exception {
		policy = loadPolicy(policyFilePath);
		File policyFile = new File(policyFilePath);
//		mutantFileNameBase = policyFile.getParent() +File.separator+"mutants"+File.separator+policyFile.getName();
		mutantFileNameBase = policyFile.getAbsolutePath();
		createTheOriginalPolicy();			// for comparison
		createCombiningAlgorithmMutants();
		createRuleEffectFlippingMutants();
		createRemoveRuleMutants();		// use i/o
		createAddNewRuleMutants();		// use i/o

		createRuleTargetTrueMutants();	// adding methods in the source code
		createRuleTargetFalseMutants();
		createRuleConditionTrueMutants();	// adding methods in the source code
		createRuleConditionFalseMutants();
		
		createFirstPermitRuleMutants(); // FPR
		createFirstDenyRuleMutants(); // FDR
		
		PolicyMutant.writePolicyMutantsSpreadSheet(mutantList, getMutantsSpreadSheetFileName());
 	}

	// Policy Related Mutation Operators---------------------------------
	// CRC
	/**
	 * Replaces the existing rule combining algorithm with another rule combining algorithm. 
	 * The set of considered rule combining algorithms is
	 * {deny-overrides, permit-overrides, first-applicable}.
	 */
	private void createCombiningAlgorithmMutants(){
		RuleCombiningAlgorithm[] combiningAlgorithms = {new DenyOverridesRuleAlg(), 
				new PermitOverridesRuleAlg(), new DenyUnlessPermitRuleAlg(), 
				new PermitUnlessDenyRuleAlg(), new FirstApplicableRuleAlg()};
		int mutantIndex=1;
		for (RuleCombiningAlgorithm algorithm: combiningAlgorithms){
			if (!policy.getCombiningAlg().getIdentifier().equals(algorithm.getIdentifier())) {
				RuleCombiningAlgorithm originalAlgorithm = (RuleCombiningAlgorithm)policy.getCombiningAlg();
				policy.setCombiningAlg(algorithm);
				StringBuilder builder = new StringBuilder();
				policy.encode(builder);
				String mutantFileName = getMutantFileName("CRC"+mutantIndex);
				mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" CRC"+mutantIndex, mutantFileName, -1));
				saveStringToTextFile(builder.toString(), mutantFileName);
				policy.setCombiningAlg(originalAlgorithm);				
				mutantIndex++;
			}
		}
	}
	
	// Rule Related Mutation Operators-----------------------------------
	// CRE...
	/**
	 * Changes the rule effect by replacing Permit with Deny or Deny with Permit.
	 */
	private void createRuleEffectFlippingMutants(){
		int mutantIndex=1;
		for (CombinerElement rule : policy.getChildElements()) {
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				Rule myrule = (Rule) tree;
				int originalEffect = myrule.getEffect();
				if (originalEffect==AbstractResult.DECISION_DENY)
					myrule.setEffect(AbstractResult.DECISION_PERMIT);
				else
					myrule.setEffect(AbstractResult.DECISION_DENY);
				StringBuilder builder = new StringBuilder();
				policy.encode(builder);
				String mutantFileName = getMutantFileName("CRE"+mutantIndex);
				mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" CRE"+mutantIndex, mutantFileName, mutantIndex));
				saveStringToTextFile(builder.toString(), mutantFileName);
				myrule.setEffect(originalEffect);
				mutantIndex++;
			}
		}

	}
	
//	private void createRemoveRuleMutants() throws Exception {
//		//int mutantIndex=1;
//		
//		for (int ruleIndex = 0; ruleIndex<policy.getChildElements().size(); ruleIndex++) {
//			
//			CombinerElement rule = policy.getChildElements().get(ruleIndex);
//			
//			PolicyTreeElement tree = rule.getElement();
//			if (tree instanceof Rule) {
//				
//				policy.getChildElements().remove(rule);
//				Rule myrule = (Rule) tree;
//				String id = myrule.getId().toString();
//				int effect = myrule.getEffect();
//				//System.out.println(effect);
//				//System.out.println(id);
//				// print the original and then modify it in text form.
//				StringBuilder builder = new StringBuilder();
//				policy.encode(builder);
//				String mutantFileName = getMutantFileName("RER"+ruleIndex);
//				mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" RER"+ ruleIndex, mutantFileName, ruleIndex));
//				
//				saveStringToTextFile(builder.toString(), mutantFileName);
//				policy.getChildElements().add(ruleIndex, rule);
//			}
//		}
//	}	
//	// unmodifiableCollection
	
	// RER use i/o.
	/**
	 * Chooses one rule and removes it. 
	 * @throws Exception
	 */
	private void createRemoveRuleMutants() throws Exception {
		int mutantIndex=1;
		for (CombinerElement rule : policy.getChildElements()) {
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				
				//policy.getChildElements().remove(rule);
				Rule myrule = (Rule) tree;
				String id = myrule.getId().toString();
				int effect = myrule.getEffect();
				//System.out.println(effect);
				//System.out.println(id);
				// print the original and then modify it in text form.
				StringBuilder builder = new StringBuilder();
				policy.encode(builder);
				String mutantFileName = getMutantFileName("RER"+mutantIndex);
				mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" RER"+mutantIndex, mutantFileName, mutantIndex));

//				policy.getChildElements().add(mutantIndex, rule);
				
				// find the corresponding rule from the string builder and remove it from the policy.
				int ruleStartingIndex = builder.indexOf("<Rule RuleId=\"" + id + "\" Effect=\"" + (effect==0 ? "Permit" : "Deny") + "\"  >"); 
				//System.out.println(ruleStartingIndex);
				int ruleEndingIndex = builder.indexOf("</Rule>", ruleStartingIndex) + 7+1; // +1 to kill the blank line.
				//System.out.println(ruleEndingIndex);
				
				builder.replace(ruleStartingIndex, ruleEndingIndex, "");
				
				saveStringToTextFile(builder.toString(), mutantFileName);
				mutantIndex++;
			}
		}
	}
	
	//unmodifiableCollection use i/o
	/**
	 * Adds a new rule containing a new combination of parameters 
	 * that is not specified in the existing rules of the policy 
	 * (the new rule will have the Permit and Deny effect). 
	 * Append the additional rule right after the rule.
	 */
	private void createAddNewRuleMutants() {
		int mutantIndex = 1;
		for (CombinerElement rule : policy.getChildElements()) {
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				// More ways of adding a rule.
				// Adding a rule method 1: Adding a mutant rule by flipping the rule effect
				Rule myrule = (Rule) tree;
				String id = myrule.getId().toString();
				int effect = myrule.getEffect();
				
				StringBuilder builder = new StringBuilder();
				policy.encode(builder);
				String mutantFileName = getMutantFileName("ANR"+mutantIndex);
				mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" ANR"+mutantIndex, mutantFileName, mutantIndex));

				// find the corresponding rule from the string builder, create a duplicate rule with negative effect.
				int ruleStartingIndex = builder.indexOf("<Rule RuleId=\"" + id + "\" Effect=\"" + (effect==0 ? "Permit" : "Deny") + "\"  >"); 
				//System.out.println(ruleStartingIndex);
				int ruleEndingIndex = builder.indexOf("</Rule>", ruleStartingIndex) + 7+1; // +1 to include '\n' to kill the blank line.
				//System.out.println(ruleEndingIndex);
				
				// pull out the rule:
				String theRule = builder.substring(ruleStartingIndex, ruleEndingIndex);
				String mutantRule = "";
				//System.out.println(theRule);
//				int effectIndex = theRule.indexOf("Effect=\"" +(effect==0 ? "Permit" : "Deny") + "\"  >");
				if (effect==0) {
					mutantRule = theRule.replace("Effect=\"" + "Permit", "Effect=\"" + "Deny"); 
				} else {
					mutantRule = theRule.replace("Effect=\"" + "Deny", "Effect=\"" + "Permit");
				}
				//System.out.println(mutantRule);
				//--------------
				// Append mutant rule to the end of the rule.
				builder.replace(ruleEndingIndex, ruleEndingIndex, mutantRule);
				
				saveStringToTextFile(builder.toString(), mutantFileName);
				
				mutantIndex++;
			}
		}
	}
	
	// FPR use i/o. create a single mutant, bugposition=0
	/**
	 * It moves in each policy the rules having a Permit effect before those ones having a Deny effect.
	 */
	private void createFirstPermitRuleMutants() {
		final int MUTANTINDEX=1; // fixed
		
		StringBuilder builder = new StringBuilder();
		policy.encode(builder);
		String mutantFileName = getMutantFileName("FPR"+MUTANTINDEX);
		mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" FPR"+MUTANTINDEX, mutantFileName, 0));
		
		// d keep tracks of the first deny rule; 
		// p keep tracks of the first permit rule after the deny rule;
		int p = -1, d = -1;	
		
		for (int i = 0; i < policy.getChildElements().size(); i++) {
			CombinerElement rule = policy.getChildElements().get(i);
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				Rule myrule = (Rule) tree;
				String id = myrule.getId().toString();
				int effect = myrule.getEffect();
				if (effect==1) {
					d = i;
					// then find the next permit rule to swap with.
					int currentindex = (p==-1 ? 0 : p); // starting searching index. avoid -1
					while(currentindex<policy.getChildElements().size()) {
						CombinerElement temprule = policy.getChildElements().get(currentindex);
						PolicyTreeElement temptree = temprule.getElement();
						if(temptree instanceof Rule) {
							Rule therule = (Rule) temptree;
							int eff = therule.getEffect();
							if(eff==0){
								p = currentindex;
								break;
							}
						}
						currentindex++;
					}
					if (p>d && p<policy.getChildElements().size()) {
						// swap rule p and rule d.
						// info about the permit rule.
						CombinerElement rulePermit = policy.getChildElements().get(p);
						PolicyTreeElement treePermit = rulePermit.getElement();
						Rule myrulePermit = (Rule) treePermit;
						String idPermit = myrulePermit.getId().toString();
						
						// find the deny rule
						int denyruleStartingIndex = builder.indexOf("<Rule RuleId=\"" + id + "\" Effect=\"" + "Deny" + "\"  >"); 
						int denyruleEndingIndex = builder.indexOf("</Rule>", denyruleStartingIndex) + 7+1; // +1 to kill the blank line.
						// find the permit rule
						int permitruleStartingIndex = builder.indexOf("<Rule RuleId=\"" + idPermit + "\" Effect=\"" + "Permit" + "\"  >"); 
						int permitruleEndingIndex = builder.indexOf("</Rule>", permitruleStartingIndex) + 7+1; // +1 to kill the blank line.
						// copy of permit rule
						String permitrule = builder.substring(permitruleStartingIndex, permitruleEndingIndex);
						// copy of deny rule
						String denyrule = builder.substring(denyruleStartingIndex, denyruleEndingIndex);
						// replace the permit rule with the deny rule
						builder.replace(permitruleStartingIndex, permitruleEndingIndex, denyrule);
						// replace the deny rule with the permit rule
						builder.replace(denyruleStartingIndex, denyruleEndingIndex, permitrule);

						//System.out.println(builder.toString());
						saveStringToTextFile(builder.toString(), mutantFileName);
						//return;
						// Important: set p = p+1;
						p++;
					}
				}
			}
		}
	}
	
	// FDR use i/o
	/**
	 * It moves in each policy the rules having a Deny effect before those ones having a Permit effect.
	 */
	private void createFirstDenyRuleMutants() {
		final int MUTANTINDEX=1; // fixed
		
		StringBuilder builder = new StringBuilder();
		policy.encode(builder);
		String mutantFileName = getMutantFileName("FDR"+MUTANTINDEX);
		mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" FDR"+MUTANTINDEX, mutantFileName, 0));
		
		// d keep tracks of the first deny rule; 
		// p keep tracks of the first permit rule after the deny rule;
		int p = -1, d = -1;	
		
		for (int i = 0; i < policy.getChildElements().size(); i++) {
			CombinerElement rule = policy.getChildElements().get(i);
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				Rule myrule = (Rule) tree;
				String id = myrule.getId().toString();
				int effect = myrule.getEffect();
				if (effect==0) {
					p = i;
					// then find the next deny rule to swap with.
					int currentindex = (d==-1 ? 0 : d); // starting searching index. avoid -1
					while(currentindex<policy.getChildElements().size()) {
						CombinerElement temprule = policy.getChildElements().get(currentindex);
						PolicyTreeElement temptree = temprule.getElement();
						if(temptree instanceof Rule) {
							Rule therule = (Rule) temptree;
							int eff = therule.getEffect();
							if(eff==1){
								d = currentindex;
								break;
							}
						}
						currentindex++;
					}
					if (d>p && d<policy.getChildElements().size()) {
						// swap rule d and rule p.
						// info about the deny rule.
						CombinerElement ruleDeny = policy.getChildElements().get(d);
						PolicyTreeElement treeDeny = ruleDeny.getElement();
						Rule myruleDeny = (Rule) treeDeny;
						String idDeny = myruleDeny.getId().toString();
						
						// find the permit rule
						int permitruleStartingIndex = builder.indexOf("<Rule RuleId=\"" + id + "\" Effect=\"" + "Permit" + "\"  >"); 
						int permitruleEndingIndex = builder.indexOf("</Rule>", permitruleStartingIndex) + 7+1; // +1 to kill the blank line.
						// find the deny rule
						int denyruleStartingIndex = builder.indexOf("<Rule RuleId=\"" + idDeny + "\" Effect=\"" + "Deny" + "\"  >"); 
						int denyruleEndingIndex = builder.indexOf("</Rule>", denyruleStartingIndex) + 7+1; // +1 to kill the blank line.
						// copy of deny rule
						String denyrule = builder.substring(denyruleStartingIndex, denyruleEndingIndex);
						// copy of permit rule
						String permitrule = builder.substring(permitruleStartingIndex, permitruleEndingIndex);
						// replace the deny rule with the permit rule
						builder.replace(denyruleStartingIndex, denyruleEndingIndex, permitrule);
						// replace the deny rule with the permit rule
						builder.replace(permitruleStartingIndex, permitruleEndingIndex, denyrule);

						//System.out.println(builder.toString());
						saveStringToTextFile(builder.toString(), mutantFileName);
						//return;
						// Important: set p = p+1;
						d++;
					}
				}
			}
		}
	}
	
	// RTT
	/**
	 * Remove the Target(if exists) OF EACH RULE ensuring that the Rule is applied to all requests.
	 */
	private void createRuleTargetTrueMutants() {	
		int mutantIndex=1;
		for (CombinerElement rule : policy.getChildElements()) {
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				Rule myrule = (Rule) tree;
				if(!myrule.isTargetEmpty()) {
					AbstractTarget target = myrule.getTarget();
					myrule.setTargetEmpty();				
					
					StringBuilder builder = new StringBuilder();
					policy.encode(builder);
					String mutantFileName = getMutantFileName("RTT"+mutantIndex);
					mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" RTT"+mutantIndex, mutantFileName, mutantIndex));
					saveStringToTextFile(builder.toString(), mutantFileName);
	
					myrule.setTarget(target);
					mutantIndex++;
				}
			}
		}

	}
	
	// target unmodifiable. use i/o 
	/**
	 * Modify the Target of each rule such that the Rule is never applied to a request.
	 */
	private void createRuleTargetFalseMutants() {
		int mutantIndex=1;
		for (CombinerElement rule : policy.getChildElements()) {
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				Rule myrule = (Rule) tree;
				String id = myrule.getId().toString();
				int effect = myrule.getEffect();
				//AbstractTarget target = myrule.getTarget();
//				// create an always-false target and replace the target in the rule.
//				Target falsetarget = new Target();
//				//falsetarget.
				
				StringBuilder builder = new StringBuilder();
				policy.encode(builder);
				String mutantFileName = getMutantFileName("RTF"+mutantIndex);
				mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" RTF"+mutantIndex, mutantFileName, mutantIndex));
				
				// find the corresponding rule from the string builder and remove it from the policy.
				int ruleStartingIndex = builder.indexOf("<Rule RuleId=\"" + id + "\" Effect=\"" + (effect==0 ? "Permit" : "Deny") + "\"  >");
				int ruleEndingIndex = builder.indexOf("</Rule>", ruleStartingIndex) + 7+1; // +1 to include '\n'
				// default target starting index.
				int targetStartingIndex = ruleStartingIndex + ("<Rule RuleId=\"" + id + "\" Effect=\"" + (effect==0 ? "Permit" : "Deny") + "\"  >").length()+1; // +1 to include '\n'
				int targetEndingIndex = -1;
				// try to search if there exists a target, if not, use the default.
				String falseTarget = "<Target>\n1=0\n</Target>\n";
				int temp = builder.indexOf("<Target>", targetStartingIndex);
				if (temp!=-1 && temp<=ruleEndingIndex) {
					// target exists, find the target ending index, and replace the target with the false target.
					targetEndingIndex = builder.indexOf("</Target>", targetStartingIndex) + 9+1; // +1 to include '\n'
					builder.replace(targetStartingIndex, targetEndingIndex, falseTarget);
				} else {
					// no existing target, add a false target.
					builder.replace(targetStartingIndex, targetStartingIndex, falseTarget);
				}
				
				//myrule.setTarget(target);
				saveStringToTextFile(builder.toString(), mutantFileName);
				mutantIndex++;
			}
		}

	}
	
	// RCT
	/**
	 * Removes the condition(if exists) of each Rule ensuring that the Condition always evaluates to True.
	 */
	private void createRuleConditionTrueMutants() {
		int mutantIndex=1;
		for (CombinerElement rule : policy.getChildElements()) {
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				Rule myrule = (Rule) tree;
				if(!myrule.isConditionEmpty()) {
					Condition condition = myrule.getCondition();
					myrule.setConditionEmpty();				
					
					StringBuilder builder = new StringBuilder();
					policy.encode(builder);
					String mutantFileName = getMutantFileName("RCT"+mutantIndex);
					mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" RCT"+mutantIndex, mutantFileName, mutantIndex));
					saveStringToTextFile(builder.toString(), mutantFileName);
	
					myrule.setCondition(condition);
					mutantIndex++;
				}
			}
		}
	}
	
	// RCF use i/o 
	/**
	 * Manipulates the Condition values or the Condition functions 
	 * ensuring that the Condition always evaluates to False.
	 */
	private void createRuleConditionFalseMutants() {
		int mutantIndex=1;
		for (CombinerElement rule : policy.getChildElements()) {
			PolicyTreeElement tree = rule.getElement();
			if (tree instanceof Rule) {
				Rule myrule = (Rule) tree;
				String id = myrule.getId().toString();
				int effect = myrule.getEffect();
				
				StringBuilder builder = new StringBuilder();
				policy.encode(builder);
				String mutantFileName = getMutantFileName("RCF"+mutantIndex);
				mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" RCF"+mutantIndex, mutantFileName, mutantIndex));
				
				// find the corresponding rule from the string builder and remove it from the policy.
				int ruleStartingIndex = builder.indexOf("<Rule RuleId=\"" + id + "\" Effect=\"" + (effect==0 ? "Permit" : "Deny") + "\"  >");
				int ruleEndingIndex = builder.indexOf("</Rule>", ruleStartingIndex) + 7+1; // +1 to include '\n'
				// default condition starting index.
				int targetStartingIndex = ruleStartingIndex + ("<Rule RuleId=\"" + id + "\" Effect=\"" + (effect==0 ? "Permit" : "Deny") + "\"  >").length()+1; // +1 to include '\n'
				int targetEndingIndex = -1;
				// try to search if there exists a target to figure out the condition starting point.
				int conditionStartingIndex = -1;
				int conditionEndingIndex = -1;
				
				int tempT = builder.indexOf("<Target>", targetStartingIndex);
				if (tempT!=-1 && tempT<=ruleEndingIndex) {
					// target exists, find the target ending index, so condition should just follow the target.
					targetEndingIndex = builder.indexOf("</Target>", targetStartingIndex) + "</Target>".length()+1; // +1 to include '\n'
					conditionStartingIndex = targetEndingIndex;
				} else {
					// no existing target
					conditionStartingIndex = targetStartingIndex;
				}
				// search if there exists a condition
				String falseCondition = "<Condition>\n1=0\n</Condition>\n"; // the false condition
				int tempC = builder.indexOf("<Condition>", conditionStartingIndex);
				if (tempC!=-1 && tempC<=ruleEndingIndex) {
					// condition exists. replace it with the false condition.
					conditionEndingIndex = builder.indexOf("</Condition>", targetStartingIndex) + "</Condition>".length()+1; // +1 to include '\n'
					builder.replace(conditionStartingIndex, conditionEndingIndex, falseCondition);
				} else {
					// no existing condition, add a false condition.
					builder.replace(conditionStartingIndex, conditionStartingIndex, falseCondition);
				}
				
				saveStringToTextFile(builder.toString(), mutantFileName);
				mutantIndex++;
			}
		}

	}
	//TODO RTR
	private void createRuleTypeReplacedMutants() {
		
	}
	
	//-----------------------------Function Related Mutation Operators
	//TODO
	private void createRemoveUniquenessFunctionMutants() {
		
	}
	//TODO
	private void createAddUniquenessFunctionMutants() {
		
	}
	//TODO
	private void createChangeNOFFunctionMutants() {
		
	}
	
	//TODO
	private void createChangeLogicalFunctionMutants() {
		
	}
	
	//TODO
	private void createAddNotFunctionMutants() {
		
	}
	
	//TODO
	private void createRemoveNotFunctionMutants() {
		
	}
	
	//TODO
	private void createChangeComparisionFunctionMutants() {
		
	}
	
	// Just print the ORIGINAL policy in the same indentation of those mutants, 
	// to get a better view of comparison with'em.
	private void createTheOriginalPolicy() {
			StringBuilder builder = new StringBuilder();
			policy.encode(builder);
			String mutantFileName = getMutantFileName("ORG");
			mutantList.add(new PolicyMutant(PolicyMutant.MUTANT_KEYWORD+" ORG", mutantFileName, 0));
			saveStringToTextFile(builder.toString(), mutantFileName);
	}
	
	// Create a mutant file name
	private String getMutantFileName(String mutantID){
		int lastDotIndex = mutantFileNameBase.lastIndexOf(".");
		if (lastDotIndex>0)
			return mutantFileNameBase.substring(0, lastDotIndex)+"_"+mutantID+".xml";
		else 
			return mutantFileNameBase+"_"+mutantID+".xml";			
	}

	private String getMutantsSpreadSheetFileName(){
		int lastDotIndex = mutantFileNameBase.lastIndexOf(".");
		if (lastDotIndex>0)
			return mutantFileNameBase.substring(0, lastDotIndex)+"_mutants.xls";
		else 
			return mutantFileNameBase+"_mutants.xls";			
	}

    public Policy loadPolicy(String policyFile) {

       Policy policy = null;
       InputStream stream = null;

       try {
           // create the factory
           DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
           factory.setIgnoringComments(true);
           factory.setNamespaceAware(true);
           factory.setValidating(false);

           // create a builder based on the factory & try to load the policy
           DocumentBuilder db = factory.newDocumentBuilder();
           stream = new FileInputStream(policyFile);
           Document doc = db.parse(stream);

           // handle the policy, if it's a known type
           Element root = doc.getDocumentElement();
           String name = DOMHelper.getLocalName(root);

           if (name.equals("Policy")) {
               policy = Policy.getInstance(root);                
           } 
       } catch (Exception e) {
       		e.printStackTrace();
       } finally {
           if(stream != null){
               try {
                   stream.close();
               } catch (IOException e) {
               }
           }
       }
     return policy;
   }
    
	public static void saveStringToTextFile(String fileString, String fileName) {
		File file = new File(fileName);
		saveStringToTextFile(fileString, file);
	}

	public static void saveStringToTextFile(String fileString, File file) {
		PrintWriter out = null;
		if (file.exists()) {
			file.delete();
		}
		try {
			out = new PrintWriter(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		out.print(fileString);
		out.close();
	}

	public static void main(String[] args) throws Exception{
		//new PolicyMutator("mutation//kmarket-blue-policy.xml");
		new PolicyMutator("mutation//pluto3.xml");
		System.out.println("Mutants generated.");
	}


}
